﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;

namespace YJKTools.ExportNavisworks
{
	public class ExportManager
	{
		public ExportManager(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		public void Export()
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			ExportSettingForm exportSettingForm = new ExportSettingForm(this.m_Revit);
			DialogResult dialogResult;
			for (;;)
			{
				dialogResult = exportSettingForm.ShowDialog();
				if (DialogResult.Yes != dialogResult)
				{
					break;
				}
				Reference reference;
				try
				{
					reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, "请选择系统中的元素");
				}
				catch
				{
					continue;
				}
				Element element = document.GetElement(reference);
				exportSettingForm.SetSystemStateByElement(element);
			}
			if (DialogResult.OK == dialogResult)
			{
				List<LevelInfo> selectedLevelInfo = exportSettingForm.GetSelectedLevelInfo();
				FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
				if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
				{
					return;
				}
				string selectedPath = folderBrowserDialog.SelectedPath;
				foreach (LevelInfo levelInfo in selectedLevelInfo)
				{
					double num = levelInfo.m_TopElevation + levelInfo.m_TopOffset;
					double num2 = levelInfo.m_BottomElevation + levelInfo.m_BottomOffset;
					BoundingBoxXYZ boundingBoxXYZ = new BoundingBoxXYZ();
					boundingBoxXYZ.Min = new XYZ(double.MinValue, double.MinValue, num2);
					boundingBoxXYZ.Max = new XYZ(double.MaxValue, double.MaxValue, num);
					Transaction transaction = new Transaction(document, "Export Navisworks");
					transaction.Start();
					View3D view3D = RevitVersionFuncs.NewView3D(document, new XYZ(-1.0, 1.0, -1.0));
					this.SetProperty(ref view3D, boundingBoxXYZ, false);
					if (exportSettingForm.m_mode == 0)
					{
						IList<ElementId> noSelectedCategories = exportSettingForm.GetNoSelectedCategories();
						if (noSelectedCategories.Count > 0)
						{
							view3D.HideCategoriesTemporary(noSelectedCategories);
						}
					}
					else if (1 == exportSettingForm.m_mode)
					{
						List<MEPSystem> selectedMEPSystems = exportSettingForm.GetSelectedMEPSystems();
						List<ElementId> list = new List<ElementId>();
						foreach (MEPSystem mepSys in selectedMEPSystems)
						{
							list.AddRange(exportSettingForm.GetElementsBySystem(mepSys));
						}
						List<ElementId> list2 = new HYSystemElementFilter(document).GetAllElementSet().ToElementIds().ToList<ElementId>();
						if (list2.Count > 0)
						{
							view3D.HideElements(list2);
						}
						if (list.Count > 0)
						{
							view3D.UnhideElements(list);
						}
					}
					transaction.Commit();
					IEnumerable<Element> enumerable = new FilteredElementCollector(document, view3D.Id).ToElements();
					List<Element> list3 = new List<Element>();
					foreach (Element element2 in enumerable)
					{
						if (element2.IsPhaseCreatedValid(element2.CreatedPhaseId))
						{
							list3.Add(element2);
						}
					}
					if (list3.Count == 0)
					{
						string text = string.Format("{0}没有可导出的实体，不生成此楼层文件。", levelInfo.m_FloorName);
						TaskDialog.Show("盈建科", text);
					}
					else
					{
						RevitVersionFuncs.ExportNavisworks(selectedPath, document, view3D.Id, levelInfo.m_FloorName);
						this.DeletePartialView3d(view3D);
					}
				}
			}
		}

		private View3D CreatePartialView3d(BoundingBoxXYZ sectionBox)
		{
			View3D view3D = null;
			Transaction transaction = null;
			transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
			transaction.Start("create view");
			View3D result;
			try
			{
				XYZ direction = new XYZ(-1.0, 1.0, -1.0);
				view3D = RevitVersionFuncs.NewView3D(this.m_Revit.Application.ActiveUIDocument.Document, direction);
				if (view3D != null)
				{
					this.SetProperty(ref view3D, sectionBox, false);
				}
				transaction.Commit();
				result = view3D;
			}
			catch (Exception)
			{
				transaction.RollBack();
				result = view3D;
			}
			return result;
		}

		private void DeletePartialView3d(View3D view3d)
		{
			Transaction transaction = null;
			transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
			transaction.Start("delete view");
			try
			{
				this.m_Revit.Application.ActiveUIDocument.Document.Delete(view3d.Id);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void SetProperty(ref View3D view3d, BoundingBoxXYZ boundingBox, bool setViewCropRegion)
		{
			view3d.SetYJKSectionBox(boundingBox);
			view3d.DetailLevel = (ViewDetailLevel)3;
            view3d.DisplayStyle = (DisplayStyle)8;
			if (setViewCropRegion)
			{
				view3d.get_Parameter(BuiltInParameter.VIEWER_CROP_REGION).Set(0);
			}
		}

		private void HideBaseline(ViewPlan floor, ref ElementId oldValue)
		{
			Transaction transaction = null;
			transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
			transaction.Start("HideBaseline");
			try
			{
				oldValue = floor.GetUnderLayParameter().AsElementId();
				floor.GetUnderLayParameter().Set(ElementId.InvalidElementId);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void UnhideBaseline(ViewPlan floor, ElementId oldValue)
		{
			Transaction transaction = null;
			transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
			transaction.Start("UnhideBaseline");
			try
			{
				floor.GetUnderLayParameter().Set(oldValue);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private ExternalCommandData m_Revit;

		private List<List<ElementId>> m_ElementIdByView = new List<List<ElementId>>();
	}
}
